package com.token.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;

import com.token.enums.FileFormatEnum;
import com.token.utils.HttpUtils;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.token.config.AliIDConfig;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @auther: henriy
 * @Date: 2023/11/28
 */
@RestController
@RequestMapping("/test")
public class AliIDController {

    /**
     * 身份证识别Api-只需要考虑正面
     * 要点：
     * 1，接口支持：PNG、JPG、JPEG、BMP、GIF、TIFF、WebP。暂不支持PDF格式；
     * 2，图片长宽需要大于15像素，小于8192像素，长宽比需要小于50；
     * 3，图片过大会影响接口响应速度，建议使用小于1.5M图片进行识别；
     * 4，只支持中国大陆身份证；
     *
     * @param file
     * @return
     */
    @SneakyThrows({Exception.class})
    @PostMapping(value = "/ocr/idcard", consumes = "multipart/form-data")
    public JSONObject ocrIdCard(@RequestParam("file") MultipartFile file) {
        JSONObject result = new JSONObject();

        if (file.isEmpty()) {
            result.put("error", "请选择上传的文件");
            return result;
        }

        List<String> fileFormatList = Arrays.stream(FileFormatEnum.values())
                .map(FileFormatEnum::getType)
                .collect(Collectors.toList());
        String fileFormat = StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
        if (!fileFormatList.contains(fileFormat)) {
            result.put("error", "暂不支持该文件格式");
            return result;
        }

        String imgBase64 = AliIDConfig.imgBase64(file);
        // configure配置，身份证正反面类型：face-对应人像面，back-对应国徽面
        JSONObject configObj = new JSONObject();
        configObj.put("side", "back");

        // 创建请求对象
        JSONObject requestObj = new JSONObject();
        requestObj.put("image", imgBase64);
        if (configObj.size() > 0) {
            requestObj.put("configure", configObj);
        }

        try {
            HttpResponse response = HttpUtils.doPost(AliIDConfig.ALI_API_HOST, AliIDConfig.ALI_API_PATH, "POST",
                    AliIDConfig.buildHeaders(), new HashMap<>(), requestObj.toJSONString());

            int stat = response.getStatusLine().getStatusCode();
            if (stat != 200) {
                result.put("error", "Http code: " + stat);
                result.put("message", EntityUtils.toString(response.getEntity()));
            } else {
                String res = EntityUtils.toString(response.getEntity());
                result = JSON.parseObject(res);
            }
        } catch (Exception e) {
            result.put("error", "OCR API调用失败");
            result.put("message", e.getMessage());
            // 记录错误而不仅仅打印堆栈跟踪
            e.printStackTrace();
        }

        System.out.println("身份证--result------" + result);
        return result;
    }

    public JSONObject checkIdcard(Object idcard, Object name) {
        JSONObject result = new JSONObject();

        Map<String, String> querys = new HashMap<>();
        querys.put("idCard", idcard.toString());
        querys.put("name", name.toString());

        try {
            HttpResponse response = HttpUtils.doPost(
                    AliIDConfig.ALI_IDCHECK_HOST,
                    AliIDConfig.ALI_IDCHECK_PATH,
                    "POST",
                    AliIDConfig.buildHeaders(),
                    querys,
                    new HashMap<>() // No need to pass an empty map for bodys
            );

            int stat = response.getStatusLine().getStatusCode();
            if (stat == 200) {
                String res = EntityUtils.toString(response.getEntity());
                result = JSON.parseObject(res);
            } else {
                result.put("error", "Http code: " + stat);
                result.put("message", EntityUtils.toString(response.getEntity()));
            }
        } catch (Exception e) {
            result.put("error", "实名认证检测失败");
            result.put("message", e.getMessage());
            // 记录错误而不仅仅打印堆栈跟踪
            e.printStackTrace();
        }

        System.out.println(result);
        return result;
    }

    /**
     * 驾驶证识别Api-只需要考虑正面
     * 要点：
     * 1，接口支持：PNG、JPG、JPEG、BMP、GIF、TIFF、WebP。暂不支持PDF格式；
     * 2，图片长宽需要大于15像素，小于8192像素，长宽比需要小于50；
     * 3，图片过大会影响接口响应速度，建议使用小于1.5M图片进行识别；
     * 4，只支持中国驾驶证；
     *
     * @param file
     * @return
     */
    @PostMapping(value = "/ocr/driverLicense", consumes = "multipart/form-data")
    public JSONObject ocrDriverLicense(@RequestParam("file") MultipartFile file) {
        JSONObject result = new JSONObject();

        if (file.isEmpty()) {
            result.put("error", "请选择上传的文件");
            return result;
        }

        List<String> fileFormatList = Arrays.stream(FileFormatEnum.values())
                .map(FileFormatEnum::getType)
                .collect(Collectors.toList());
        String fileFormat = StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
        if (!fileFormatList.contains(fileFormat)) {
            result.put("error", "暂不支持该文件格式");
            return result;
        }

        String host = "https://cardriving.market.alicloudapi.com";
        String path = "/rest/160601/ocr/ocr_driver_license.json";
        String appcode = "22bedbce1cf447e38998e6b2e53987bf";
        // 如果文档的输入中含有inputs字段，设置为True，否则设置为False
        // boolean isOldFormat = true;
        // 请根据线上文档修改configure字段
        JSONObject configObj = new JSONObject();
        // 首页/副页:face/back
        configObj.put("side", "face");
        String configStr = configObj.toString();

        String method = "POST";
        Map<String, String> headers = new HashMap<>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        Map<String, String> querys = new HashMap<>();

        // 对图像进行base64编码
        String imgBase64 = AliIDConfig.imgBase64(file);
        // 拼装请求body的json字符串
        JSONObject requestObj = new JSONObject();
        JSONObject obj = new JSONObject();
        obj.put("image", getParam(50, imgBase64));
        if (configStr.length() > 0) {
            obj.put("configure", getParam(50, configStr));
        }
        JSONArray inputArray = new JSONArray();
        inputArray.add(obj);
        requestObj.put("inputs", inputArray);

        String bodys = requestObj.toString();
        try {
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            int stat = response.getStatusLine().getStatusCode();
            if (stat != 200) {
                System.out.println("Http code: " + stat);
                System.out.println("http header error msg: " + response.getFirstHeader("X-Ca-Error-Message"));
                System.out.println("Http body error msg：" + EntityUtils.toString(response.getEntity()));
                return result;
            }

            String res = EntityUtils.toString(response.getEntity());
            JSONObject parseResult = JSON.parseObject(res);
            JSONArray outputArray = parseResult.getJSONArray("outputs");
            String output = outputArray.getJSONObject(0)
                    .getJSONObject("outputValue")
                    .getString("dataValue");
            result = JSON.parseObject(output);
            System.out.println("驾驶证--result------" + result);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 获取参数的json对象
     *
     * @param type
     * @param dataValue
     * @return
     */
    public static JSONObject getParam(int type, String dataValue) {
        JSONObject obj = new JSONObject();
        try {
            obj.put("dataType", type);
            obj.put("dataValue", dataValue);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return obj;
    }

    /**
     * 行驶证Api-只需要考虑正面
     * 要点：
     * 1，接口支持：PNG、JPG、JPEG、BMP、GIF、TIFF、WebP。暂不支持PDF格式；
     * 2，图片长宽需要大于15像素，小于8192像素，长宽比需要小于50；
     * 3，图片过大会影响接口响应速度，建议使用小于1.5M图片进行识别；
     * 4，只支持中国行驶证；
     *
     * @param file
     * @return
     */
    @PostMapping(value = "/ocr/drivingLicense", consumes = "multipart/form-data")
    public JSONObject ocrDrivingLicense(@RequestParam("file") MultipartFile file) {
        JSONObject result = new JSONObject();

        if (file.isEmpty()) {
            result.put("error", "请选择上传的文件");
            return result;
        }

        List<String> fileFormatList = Arrays.stream(FileFormatEnum.values())
                .map(FileFormatEnum::getType)
                .collect(Collectors.toList());
        String fileFormat = StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
        if (!fileFormatList.contains(fileFormat)) {
            result.put("error", "暂不支持该文件格式");
            return result;
        }

        String host = "https://driving.market.alicloudapi.com";
        String path = "/rest/160601/ocr/ocr_vehicle.json";
        String appcode = "22bedbce1cf447e38998e6b2e53987bf";
        //请根据线上文档修改configure字段
        JSONObject configObj = new JSONObject();
        configObj.put("side", "face");
        String configStr = configObj.toString();

        String method = "POST";
        Map<String, String> headers = new HashMap<>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        Map<String, String> querys = new HashMap<>();

        // 对图像进行base64编码
        String imgBase64 = AliIDConfig.imgBase64(file);

        // 拼装请求body的json字符串
        JSONObject requestObj = new JSONObject();
        JSONObject obj = new JSONObject();
        obj.put("image", getParam(50, imgBase64));
        if (configStr.length() > 0) {
            obj.put("configure", getParam(50, configStr));
        }
        JSONArray inputArray = new JSONArray();
        inputArray.add(obj);
        requestObj.put("inputs", inputArray);

        String bodys = requestObj.toString();
        try {
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            int stat = response.getStatusLine().getStatusCode();
            if (stat != 200) {
                System.out.println("Http code: " + stat);
                System.out.println("http header error msg: " + response.getFirstHeader("X-Ca-Error-Message"));
                System.out.println("Http body error msg:" + EntityUtils.toString(response.getEntity()));
                return result;
            }

            String res = EntityUtils.toString(response.getEntity());
            JSONObject parseResult = JSON.parseObject(res);
            JSONArray outputArray = parseResult.getJSONArray("outputs");
            String output = outputArray.getJSONObject(0)
                    .getJSONObject("outputValue")
                    .getString("dataValue");
            result = JSON.parseObject(output);
            System.out.println("行驶证--result------" + result);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }


    /**
     * 银行卡Api-只需要考虑正面
     *
     * @param file
     * @return
     */
    @PostMapping(value = "/ocr/bankCard", consumes = "multipart/form-data")
    public JSONObject ocrBankCard(@RequestParam("file") MultipartFile file) {
        JSONObject result = new JSONObject();

        String host = "https://yhk.market.alicloudapi.com";
        String path = "/rest/160601/ocr/ocr_bank_card.json";
        String method = "POST";
        String appcode = "22bedbce1cf447e38998e6b2e53987bf";
        Map<String, String> headers = new HashMap<>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        headers.put("Content-Type", "application/json; charset=UTF-8");

        // #图片以base64编码的string，return bank card type
        JSONObject requestObj = new JSONObject();
        requestObj.put("image", AliIDConfig.imgBase64(file));
        requestObj.put("configure", "{\\\"card_type\\\":true}");
        String body = requestObj.toString();

        try {
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, new HashMap<>(), body);
            System.out.println("=============" + response.toString());
            //获取response的body
            String entity = EntityUtils.toString(response.getEntity());
            JSONObject jsonObject = JSONObject.parseObject(entity);

            System.out.println("银行卡---result-----" + jsonObject);
            result.put("bankName", jsonObject.get("bank_name"));
            result.put("cardNum", jsonObject.get("card_num"));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

}

